/**
 * 
 */
package com.tiduyun.data.exchange.util;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.lang3.StringUtils;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.TypeFactory;

import lombok.extern.slf4j.Slf4j;

/**
 * @author wuzheng@tiduyun.com
 *
 */
@Slf4j
public class JSONUtils {

    private static final ObjectMapper JACKSON_OBJECT_MAPPER = createJacksonObjectMapper();

    private static ObjectMapper createJacksonObjectMapper() {
        ObjectMapper mapper = new ObjectMapper();
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        return mapper;
    }

    public static String toJSONString(Object object) throws JsonProcessingException {
        if (object == null) {
            return null;
        }
        return JACKSON_OBJECT_MAPPER.writeValueAsString(object);
    }

    public static String toJSONStringIgnoreErrors(Object object) {
        try {
            return toJSONString(object);
        } catch (Exception e) {
            log.warn("Serialize object to json failed: object={}", object, e);
            return null;
        }
    }

    public static <T> T parse(String json, Class<T> clazz) throws JsonProcessingException, IOException {
        if (StringUtils.isEmpty(json)) {
            return null;
        }
        return JACKSON_OBJECT_MAPPER.readValue(json, clazz);
    }

    public static <T> T parseIgnoreErrors(String json, Class<T> clazz, T defaultValue) {
        try {
            T result = parse(json, clazz);
            if (result != null) {
                return result;
            }
        } catch (Exception e) {
            log.warn("Parse object from json failed: json={}, class={}", json, clazz, e);
        }
        return defaultValue;
    }

    public static <T> T parseIgnoreErrors(String json, Class<T> clazz) {
        return parseIgnoreErrors(json, clazz, null);
    }

    @SuppressWarnings("unchecked")
    public static Map<String, Object> parseMap(String json) throws JsonProcessingException, IOException {
        return parse(json, Map.class);
    }

    @SuppressWarnings("unchecked")
    public static Map<String, Object> parseMapIgnoreErrors(String json) {
        return parseIgnoreErrors(json, Map.class, null);
    }

    @SuppressWarnings("unchecked")
    public static Map<String, Object> parseMapIgnoreErrors(String json, Map<String, Object> defaultValue) {
        return parseIgnoreErrors(json, Map.class, defaultValue);
    }

    public static <T> List<T> parseList(String json, Class<T> clazz) throws JsonProcessingException, IOException {
        if (StringUtils.isEmpty(json)) {
            return null;
        }
        List<T> list = JACKSON_OBJECT_MAPPER.readValue(json,
                TypeFactory.defaultInstance().constructCollectionType(ArrayList.class, clazz));
        return list;
    }

    public static <T> List<T> parseListIgnoreErrors(String json, Class<T> clazz) {
        return parseListIgnoreErrors(json, clazz, null);
    }

    public static <T> List<T> parseListIgnoreErrors(String json, Class<T> clazz, List<T> defaultValue) {
        try {
            List<T> result = parseList(json, clazz);
            if (result != null) {
                return result;
            }
        } catch (Exception e) {
            log.warn("Parse object from json failed: json={}, class={}", json, clazz, e);
        }
        return defaultValue;
    }
    
    public static void main(String[] args) throws JsonProcessingException, IOException {
        String s = "{ztm:'2',kprq:'2020-03-01 08:56:16',swjgMc:'国家税务总局百色市右江区税务局龙景税务分局',fpccArry:'null'}";
        Pattern p = Pattern.compile(".*[\\{,]ztm:'(.+?)'.+");
//        Pattern p = Pattern.compile("ztm:'(.+)'");
        Matcher m = p.matcher(s);
        System.out.println(m.matches());
        String ztm = m.group(1);
        System.out.println(ztm);
//        System.out.println(JSONUtils.parseMap());
    }

}
